package main

import (
	"bs09-object/entry/queue"
	"bs09-object/entry/tree"
	"fmt"
	"golang.org/x/tools/container/intsets"
)

//组合方式, 扩展已有类型
type myTreeNode struct {
	node *tree.Node
}

//后续遍历
func (myNode *myTreeNode) postOrder() {
	if myNode == nil || myNode.node == nil {
		return
	}

	//需要将 myTreeNode{myNode.node.Left} 抽取成变量,以防go无法将其动态解析为地址进行调用
	//myTreeNode{myNode.node.Left}.postOrder()
	left := myTreeNode{myNode.node.Left}
	left.postOrder()
	right := myTreeNode{myNode.node.Right}
	right.postOrder()
	myNode.node.Print()
}

func main() {
	DefinedAndInitUdfType()
	testMyTreeNode()
	testQueue()
	testSparse()
}

func testSparse() {
	fmt.Println("-------- testSparse --------")
	s := intsets.Sparse{}

	s.Insert(1)
	s.Insert(1000)
	s.Insert(1000000)
	fmt.Println(s.Has(1000))
	fmt.Println(s.Has(100000))
}

func testQueue() {
	fmt.Println("-------- testQueue --------")
	q := queue.Queue{1}
	q.Push("b")
	q.Push(3)
	fmt.Println(q.Pop())
	fmt.Println(q.Pop())
	fmt.Println(q.IsEmpty())
	fmt.Println(q.Pop())
	fmt.Println(q.IsEmpty())
}

func testMyTreeNode() {
	fmt.Println("-------- testMyTreeNode --------")
	var root tree.Node
	//初始化一个值
	root = tree.Node{Value: 3}
	//默认值初始化
	root.Left = &tree.Node{}
	root.Left.Right = tree.CreateNode(2)
	//不指定字段初始化需要给所有字段赋值
	root.Right = &tree.Node{5, nil, nil}
	//注意: 指针类型(*)在go中也可以用 . 来获取其值
	root.Right.Left = new(tree.Node)

	myNode := myTreeNode{node: &root}
	myNode.postOrder()

	fmt.Println()
}

func DefinedAndInitUdfType() {
	var root tree.Node
	//初始化一个值
	root = tree.Node{Value: 3}
	//默认值初始化
	root.Left = &tree.Node{}
	root.Left.Right = tree.CreateNode(2)
	//不指定字段初始化需要给所有字段赋值
	root.Right = &tree.Node{5, nil, nil}
	//注意: 指针类型(*)在go中也可以用 . 来获取其值
	root.Right.Left = new(tree.Node)
	/*
			3
		0		5
		  2   0
	*/
	fmt.Println("root=", root, " root.left=", root.Left, " root.right", root.Right)

	root.Print()
	tree.Print(root)
	fmt.Println()

	//这里需要注意值传递还是引用传递
	root.Right.Left.SetValue(4)
	root.Right.Left.Print()
	fmt.Println()

	var nilRoot *tree.Node
	nilRoot.SetValue(200)
	nilRoot = tree.CreateNode(100)
	nilRoot.SetValue(300)
	nilRoot.Print()
	fmt.Println()

	root.Traverse()
	fmt.Println()
	fmt.Println()
}
